package com.neo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Flux;

import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("routes")
public class RouteController {

    @Autowired
    private DynamicRouteServiceImpl dynamicRouteService;

    @GetMapping
    public Flux<RouteDefinition> get() {
        return Flux.just(dynamicRouteService.getRoutes().toArray(new RouteDefinition[0]));
    }

    @PostMapping("saveGateway")
    public Flux<Boolean> saveGateway(@RequestBody ReceiverConfigApiGateway receiverConfigApiGateway) {
//        ReceiverConfigApiGateway receiverConfigApiGateway = new ReceiverConfigApiGateway();
        RouteDefinition routeDefinition = assembleRouteDefinition(receiverConfigApiGateway);
        if (dynamicRouteService.save(routeDefinition)) {
            return Flux.just(true);
        } else {
            return Flux.just(false);
        }
    }

    @PostMapping("save")
    public Flux<Boolean> save(@RequestBody List<RouteDefinition> routeDefinitions) {
        if (dynamicRouteService.save(routeDefinitions)) {
            return Flux.just(true);
        } else {
            return Flux.just(false);
        }
    }

    @PostMapping("cover")
    public Flux<Boolean> cover(@RequestBody List<RouteDefinition> routeDefinitions) {
        if (dynamicRouteService.cover(routeDefinitions)) {
            return Flux.just(true);
        } else {
            return Flux.just(false);
        }
    }

    @GetMapping("delete/{routeId}")
    public Flux<Boolean> delete(@PathVariable String routeId) {
        if (dynamicRouteService.delete(routeId)) {
            return Flux.just(true);
        } else {
            return Flux.just(false);
        }
    }

    //把传递进来的参数转换成路由对象
    private RouteDefinition assembleRouteDefinition(ReceiverConfigApiGateway receiverConfigApiGateway) {
        RouteDefinition definition = new RouteDefinition();
        definition.setId(receiverConfigApiGateway.getId());
        definition.setOrder(receiverConfigApiGateway.getOrder());

        //设置断言
        List<PredicateDefinition> pdList = new ArrayList<>();
        List<Map<String, String>> gatewayPredicateDefinitionList = receiverConfigApiGateway.getPredicatesArgs();
        for (int i = 0; i < gatewayPredicateDefinitionList.size(); i++) {
            PredicateDefinition predicate = new PredicateDefinition();
            predicate.setName(receiverConfigApiGateway.getPredicatesName().get(i));
            predicate.setArgs(gatewayPredicateDefinitionList.get(i));
            pdList.add(predicate);
        }
        definition.setPredicates(pdList);

        //设置过滤器
        List<FilterDefinition> filters = new ArrayList();
        List<Map<String, String>> gatewayFilters = receiverConfigApiGateway.getFiltersArgs();
        for (int i = 0; i < gatewayFilters.size(); i++) {
            FilterDefinition filter = new FilterDefinition();
            filter.setName(receiverConfigApiGateway.getFiltersName().get(i));
            filter.setArgs(gatewayFilters.get(i));
            filters.add(filter);
        }
        definition.setFilters(filters);

        URI uri = null;
        if (receiverConfigApiGateway.getUri().startsWith("http")) {
            uri = UriComponentsBuilder.fromHttpUrl(receiverConfigApiGateway.getUri()).build().toUri();
        } else {
            // uri为 lb://consumer-service 时使用下面的方法
            uri = URI.create(receiverConfigApiGateway.getUri());
        }
        definition.setUri(uri);
        return definition;
    }

}
